import { debounce } from '@peng_kai/kit/libs/lodash-es';

document.documentElement.classList.add('tg');

Telegram?.WebApp.enableClosingConfirmation?.();
Telegram?.WebApp.expand?.();
Telegram?.WebApp.disableVerticalSwipes?.();

declare global {
  interface Window {
    tgLogicHistory: TItemLogicHistory[];
  }
}

interface TItemLogicHistory {
  type: 'route-push' | 'route-back' | 'model';
  data?: any;
  onBack?: () => void;
};

/**
 * 定义 TG 的逻辑路由，用于控制TG端左上角的"返回"按钮的行为
 */
{
  window.tgLogicHistory = new Proxy([] as TItemLogicHistory[], {
    set(target, p, newValue, receiver) {
      p === 'length' && setTimeout(onLengthChange, 10);

      return Reflect.set(target, p, newValue, receiver);
    },
  });

  Telegram.WebApp.onEvent('backButtonClicked', () => {
    const lastHistory = window.tgLogicHistory.pop();
    lastHistory?.onBack?.();
  });

  function onLengthChange() {
    if (window.tgLogicHistory.length) {
      !Telegram.WebApp.BackButton.isVisible && Telegram.WebApp.BackButton.show();
    }
    else {
      Telegram.WebApp.BackButton.hide();
    }
  }
}

/**
 * 基于 TG 的逻辑路由控制“返回”按钮的显示/隐藏
 */
{
  let continuousBackCount = 0;

  function onPush() {
    continuousBackCount = 0;
    window.tgLogicHistory.push({
      type: 'route-push',
      onBack: () => {
        if (++continuousBackCount >= 4) {
          setTimeout(() => Telegram.WebApp.BackButton.hide(), 100);
        }

        history.back();
      },
    });
  }

  decorateHistory('pushState', onPush);
  decorateHistory('forward', onPush);
  decorateHistory('go', delta => (delta ?? 0) >= 0 && onPush());

  function decorateHistory<N extends FunctionKeys<History>>(
    name: N,
    callback: (...args: Parameters<History[N]>) => any,
  ) {
    const cb = debounce(callback, 500, { leading: false });

    window.history[name] = new Proxy(window.history[name], {
      apply(target, thisArg, argumentsList) {
        cb(...argumentsList as any);
        return Reflect.apply(target, thisArg, argumentsList);
      },
    });
  }

  type FunctionKeys<T> = keyof {
    [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never
  };
}
